<?php
// +----------------------------------------------------------------------
// | INPHP
// | Copyright (c) 2023 https://inphp.cc All rights reserved.
// | Licensed ( https://opensource.org/licenses/MIT )
// | Author: 幺月儿(https://gitee.com/lulanyin) Email: inphp@qq.com
// +----------------------------------------------------------------------
// | 路由处理
// +----------------------------------------------------------------------
namespace Inphp\Core;

use Inphp\Core\Object\RouterStatus;

class Router
{
    /**
     * 路由匹配记录
     * @var RouterStatus[]
     */
    public static array $list = [];

    /**
     * 获取路由记录
     * @param string $host
     * @param string $uri
     * @return RouterStatus|null
     */
    public static function get(string $host, string $uri): ?RouterStatus
    {
        $key = md5($host."/".$uri);
        $cache = self::$list[$key] ?? null;
        if ($cache) {
            $status = $cache["status"];
            $status->status = $cache["httpStatus"];
            return $status;
        }
        return null;
    }

    /**
     * 保存路由记录
     * @param string $host
     * @param string $uri
     * @param RouterStatus $routerStatus
     */
    public static function set(string $host, string $uri, RouterStatus $routerStatus): void
    {
        //非开发模式下才会保存
        if ((defined("DEV_MODE") && !DEV_MODE) || !defined("DEV_MODE")) {
            $key = md5($host."/".$uri);
            $status = $routerStatus->status;
            self::$list[$key] = [
                "httpStatus"    => $status,
                "status"        => $routerStatus
            ];
        }
    }

    /**
     * 处理获得路由状态
     * @param string $host
     * @param string $uri
     * @param string $requestMethod
     * @param string $serviceType
     * @return RouterStatus
     */
    public static function process(string $host, string $uri = "", string $requestMethod = "GET", string $serviceType = Service::HTTP): RouterStatus
    {
        //问号后面的直接忽略掉
        if (stripos($uri, "?") > 0) {
            $uri = substr($uri, 0, stripos($uri, "?"));
        }
        //清除多余斜杠
        $uri = str_replace("\\", "/", $uri);
        $uri = str_replace("//", "/", $uri);
        //删除首个斜杠
        $uri = stripos($uri, "/") === 0 ? substr($uri, 1) : $uri;
        //删除结尾的斜杠
        $uri = strrchr($uri, "/") === "/" ? substr($uri, 0, -1) : $uri;
        //过滤谷歌浏览器的 favicon.ico 请求
        if ($uri === "favicon.ico") {
            return new RouterStatus([
                "status"        => 200,
                "message"       => null,
                "state"         => null,
                "uri"           => $uri
            ]);
        }
        //在缓存中查找，仅支持 uri 不为空时
        $statusCache = !empty($uri) ? self::get($host, $uri) : null;
        if ($statusCache) {
            Context::set("module", $statusCache->module);
            return $statusCache;
        }
        //中间件
        $middleware = Middlewares::get("onRouter");
        $middleware = is_array($middleware) ? ($middleware[0] ?? null) : $middleware;
        if (!empty($middleware) && ($middleware instanceof \Closure || function_exists($middleware))) {
            $res = call_user_func_array($middleware, [$host, $uri, $requestMethod, $serviceType]);
            if ($res instanceof RouterStatus) {
                //保存当前模块到上下文
                Context::set("module", $res->module);
                return $res;
            }
        }
        //使用模块内部处理
        $status = Modules::matchRouterStatus($host, $uri, $requestMethod, $serviceType);
        //补充uri
        $status->uri = $uri;
        //保存到临时数据
        self::set($host, $uri, $status);
        //保存当前模块到上下文
        Context::set("module", $status->module);
        //返回状态
        return $status;
    }
}